\chapter{Bigtop Syntax}
\label{chap:bigsyntax}

This chapter follows up on the previous chapter by providing Bigtop source
file syntax documentation.\index{bigtop!syntax}
While tentmaker is frequently convenient, and
it sure types more accurately than I do, it can be tedious for some edits.
In those cases, a good text editor can be a life extender.  There also
a couple of things tentmaker does not know how to edit: controller level
literals and config blocks, and join table fields and data statements.

The definitive word on what statements can appear in a Bigtop file is
maintained in Bigtop::Keywords.\index{Bigtop::Keywords}
It is used by all the current backends
and thus provides a standard place to make the definitions.  I referred
to it heavily while writing this.  If you are writing a backend, it is
vital for everyone's sanity that you place your keywords there instead
of in some ad hoc place.

\section{Basic Structure}

Bigtop files have a basic structure.\index{bigtop!syntax!basic structure}
At the top level, there are two
blocks:

{\footnotesize
\begin{verbatim}
config {
}
app Name {
}
\end{verbatim}
}

Inside the blocks there are statements and blocks.
Statements\index{bigtop!statements}
usually have
a single keyword followed by a value and a semi-colon\footnote{Literal
statements are an exception to that rule.  They have a type.  See below.}.
Block structures vary depending on
where they appear.  It is easier to understand this with an example.
Here is the smallest one that bigtop or tentmaker will make with the new
flag and one table in the ASCII art:\index{bigtop!small default}

{\footnotesize
\begin{verbatim}
config {
    engine CGI;
    template_engine TT;
    Init Std {  }
    SQL SQLite {  }
    SQL Postgres {  }
    SQL MySQL {  }
    CGI Gantry { gen_root 1; with_server 1; flex_db 1; }
    Control Gantry { dbix 1; }
    Model GantryDBIxClass {  }
    SiteLook GantryDefault {  }
}
app Test {
    config {
        dbconn `dbi:SQLite:dbname=app.db` => no_accessor;
        template_wrapper `genwrapper.tt` => no_accessor;
    }
    table tbl1 {
        field id {
            is int4, primary_key, auto;
        }
        field ident {
            is varchar;
            label Ident;
            html_form_type text;
        }
        field description {
            is varchar;
            label Description;
            html_form_type text;
        }
        field created {
            is datetime;
        }
        field modified {
            is datetime;
        }
        foreign_display `%ident`;
    }
    controller Tbl1 is AutoCRUD {
        controls_table tbl1;
        rel_location tbl1;
        text_description tbl1;
        page_link_label Tbl1;
        method do_main is main_listing {
            cols ident, description;
            header_options Add;
            row_options Edit, Delete;
            title Tbl1;
        }
        method form is AutoCRUD_form {
            all_fields_but id, created, modified;
            extra_keys
                legend =>
                `$self->path_info =~ /edit/i ? 'Edit' : 'Add'`;
        }
    }
}
\end{verbatim}
}

Here we see the basic structure of a bigtop file, the remaining sections in
this chapter explain all of the legal syntax which can go in that structure.

\section{The config Block}

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Keyword & Example Values \\
\hline
\verb+engine+ & CGI, MP13, or MP20 (the last two are \\
              & for \verb+mod_perl+)                 \\
\verb+template_engine+ & TT or Default \\
\end{tabular}
\end{center}
\caption{Bigtop config block statements.}
\label{tab:bigconfigstats}
\end{table}

In normal use, a
config\index{bigtop!config section}\index{config section, in Bigtop files}
section can have only two
statements\footnote{there are deprecated statements not covered here}.
The legal statements
are shown in Table \ref{tab:bigconfigstats}.
The \verb+engine+\index{engine!bigtop statement}
is the framework engine you will use.  Gantry supports
CGI -- which also works for Fast/CGI -- and \verb+mod_perl+ 1.3 and 2.0.
Use MP13 or MP20 for \verb+mod_perl+.
The \verb+template_engine+s\index{template!engine!bigtop statement}
supported by Gantry are Template Toolkit (TT)
or Default.  The Default
template engine does almost nothing, thus allowing you complete control
over what is returned to the browser.  See Subsection \ref{ssec:templateproc}
for an example of how to use this in unorthodox ways.

Subblocks of the Bigtop config block have two names and a set of statements
in braces.  The set of statements could be empty.  Use statements to tweak
what the backend will generate.  This chapter will not cover the statements,
since they are already fully discussed in Chapter \ref{chap:backends}.

The names of a backend block give its type (or family) and its name.
Again, all of those are discussed in Chapter \ref{chap:backends}.
If you work in bigtop files, just use the type and backend names
as discussed there.  For example, if you want MySQL\index{MySQL!in bigtop}
output, include
this block:

{\footnotesize
\begin{verbatim}
    SQL MySQL {}
\end{verbatim}
}

SQL is the backend type.  MySQL is the name of the backend.
There are other backends of the same type: Postgres and
SQLite.  Consult tentmaker for a list
of all backends installed on your system.

\section{The app Block }

The app block\index{app block in bigtop}\index{bigtop!app section}
of a Bigtop file is far more interesting than the top level
config block.  It contains the configuration information for the app,
together with a description of its tables and controllers.  This section
has subsections for each block type in the app block.  But let's start
with a subsection on app level statements.

\subsection{App
Statements\index{bigtop!app statements}\index{app statements!bigtop}}

As with the top level config block, the app block can have statements.
We will now cover the same ground as subsection \ref{ssec:appstat},
but with a focus on Bigtop syntax rather
than where to click in tentmaker.

Note that there are different types of statement
values.\index{bigtop!statement values}\index{values, in bigtop}
In general,
statements may accept comma separated lists of values.  Each element in
that list may be a single item or a pair.  If it is a single item,
it must either be a number, a valid Perl ident, or be enclosed in backquotes.
Yes, I said backquotes.  These make it easier to embed Perl's other quotes.
You shouldn't need Perl's backquotes in a web app.

The two pieces of a pair\index{pair, in bigtop}\index{bigtop!pair}
are separated with fat commas: \verb+=>+.
These are not related
to commas.  In Perl, a fat comma is a comma which forces its left argument
to string context.  In Bigtop a fat comma makes a hash with a single key.

The \verb+authors+ statement provides a good example of value variety:

{\footnotesize
\begin{verbatim}
    authors `Phil Crow` => `philcrow2000@yahoo.com`,
            `Joe Doe`,
            Bill;
\end{verbatim}
}

There are three items in this list.  The first one is a pair.  The other
two are single values.  OK, so Bill isn't so helpful,
but it is legal.  Note the use of backquotes to hide spaces,
at signs, or anything else Perl wouldn't like in an identifier.
Other statements may or may not allows multiple values and/or
pairs as indicated in Table \ref{tab:appstats1}.

\begin{table}
\begin{center}
\begin{tabular}{l|l|l}
Keyword & Meaning & Values \\
\hline
\verb+location+         & base URL absolute & one string \\
                        & from doc root \\
\verb+authors+          & who works on & multiple strings or pairs\\
                        & the app & \\
\verb+contact_us+       & how to join the app & one string \\
\verb+copyright_+-      & who owns the app & one string \\
\verb+holder+           & & \\
\verb+license_text+     & exact text & one string \\
\verb+stub_uses+ & modules used in  & multiple module names\\
                 & base stub module \\
\verb+gen_uses+  & modules used in  & multiple module names\\
                 & base gen module  \\
\verb+uses+      & modules used in  & multiple module names\\
\verb+uses+      & base module      \\
\end{tabular}
\end{center}
\caption{App level statements (similar to Table \ref{tab:appstats2}).}
\label{tab:appstats1}
\end{table}

Note that most of these will have no effect after initial generation.
All of them, except \verb+location+, \verb+gen_uses+, and \verb+uses+,
only put things into
stub code.  Stub code is never overwritten.

\verb+uses+ will be effective after initial generation, but only because
it puts things into the GEN module.  It will not put use statements into the
stub after it is written.  It's cleaner to explicitly list modules
with either \verb+stub_uses+\index{stub uses@\verb+stub_uses+}
or \verb+gen_uses+\index{gen uses@\verb+gen_uses+} in the
base controller block.

Using \verb+location+ is marginally deprecated.  If you need to specify one,
put it in a \verb+base_controller+ block, as described below.

\subsection{Literals}

Literals\index{literal statements!bigtop}\index{bigtop!literal statements}
allow you to put literal text directly into generated output.
In order to control which backends use your literal content, literals have a
type.  So they look something like this:

{\footnotesize
\begin{verbatim}
    literal SQL
      `INSERT INTO tbl1 ( ident ) VALUES ( 'somename' );`;
\end{verbatim}
}

The type of this literal is `SQL,' meaning that only SQL backends will
respond to it.  At present all literals have a single type, so all SQL
backends will use all literals of that type.

The value of each literal must be enclosed in backquotes and will be used
as is, with one exception.  If you don't have trailing whitespace, one new
line will be added to the literal.

The \ref{sssec:tentliteral} subsubsection of Chapter \ref{chap:tentref} has
a complete
list of the literal types and where their output goes.  See, in particular,
Table \ref{tab:applits}.

\subsection{Tables}

A table block\index{tables!blocks in bigtop}\index{bigtop!table blocks}
looks basically like this:

{\footnotesize
\begin{verbatim}
    table name {
    }
\end{verbatim}
}

Inside the block you may use
table statements\index{table statements}
or include field blocks
(described below).  The legal statements are in Table \ref{tab:tablestats2}.

\begin{table}
\begin{center}
\begin{tabular}{l|l|l}
Keyword & Meaning & Values \\
\hline
\verb+no_gen+  & skip this table (boolean) & Perl truth \\
\verb+not_for+ & backend types which       & SQL, Model, \\
               & skip this table           & or both \\
\verb+sequence+         & name of sequence block & one ident \\
                        & for this table \\
\verb+data+ & initial SQL data & list of column \\
            & (repeatable)     & value pairs \\
\verb+foreign_display+  & how other tables & one string \\
                        & see our rows     & \\
\verb+model_base_class+ & what model inherits from & one module \\
\end{tabular}
\end{center}
\caption{Table statements (same as Table \ref{tab:tablestats1}).}
\label{tab:tablestats2}
\end{table}

Note that boolean statements evaluate their values for Perl
truth.\index{Perl truth, in
bigtop}\index{bigtop!booleans}\index{boolean!Bigtop}
Usually, I use \verb+1+ for true and leave the statement out for false.

To list both \verb+not_for+\index{not for@\verb+not_for+ SQL and/or Model}
choices, put them in a list (order doesn't matter):

{\footnotesize
\begin{verbatim}
        not_for SQL, Model;
\end{verbatim}
}

Most statements in Bigtop must be unique within their block, but data
statements\index{tables!data statements}\index{data statements}
are an exception.  Repeat these to create as many rows as your
table needs:

{\footnotesize
\begin{verbatim}
    data ident => INPROG, descr => `Working on it`;
    data ident => BILLED, descr => `Bill has been sent`;
\end{verbatim}
}

Duplicating other statements leads to unpredictable results, which may
include fatal errors or corrupted output.

Use percents to gain interpolation in a
\verb+foreign_display+:\index{foreign display@\verb+foreign_display+}

{\footnotesize
\begin{verbatim}
    foreign_display `%last_name, %first_name (%user_name)`;
\end{verbatim}
}

Every word following a percent immediately must be a field name.  Everything
else is literal.

\subsubsection{Fields}

Fields\index{fields!bigtop blocks}\index{bigtop!field blocks}
describe columns in SQL tables and entry elements on HTML forms
where users supply that data.  They allow the
statements\index{fields!statments} shown in
Table \ref{tab:fieldstats1}.

\begin{table}
\begin{center}
\begin{tabular}{l|l|l}
Keyword & Meaning & Values \\
\hline
\verb+no_gen+  & skip this field (boolean) & Perl truth \\
\verb+not_for+ & backends which skip & SQL, Model, \\
               & this field          & or both \\
\verb+is+ & SQL column definition & a list of strings, \\
          & clauses               & see below \\
\verb+refers_to+ & foreign table this field & one table name \\
                 & refers to &  \\
\verb+label+ & on screen label for field & one string \\
\verb+non_essential+ & delayed fetch & Perl truth, \\
                     & (boolean)     & see below \\
\verb+date_select_text+ & link text for  & one string \\
                        & popup calendar & \\
\end{tabular}
\end{center}
\caption{Field statements (similar to Table \ref{tab:fieldstats2}).}
\label{tab:fieldstats1}
\end{table}

In addition to those statements, there are a set of statements which are
passed through to the form template.  These all have the
\verb+html_form_+\index{html form@\verb+html_form_+ field statments}
prefix, which is stripped before passing the data to the template.  The
names are completely governed by the template, but they should be listed
in Bigtop::Keywords and must be registered by a backend.
Table \ref{tab:fieldhtmlstats1} shows all of the form template statements,
without their prefix.

\begin{table}
\begin{center}
\begin{tabular}{l|l|l}
Keyword & Meaning & Values \\
\verb+html_form_+... & & \\
\hline
\verb+type+  & form element type & one of \verb+text+, \\
             &                   & \verb+textarea+, \\
             &                   & \verb+display+, \\
             &                   & \verb+select+, or \\
             &                   & \verb+select_multiple+ \\
\verb+optional+ & Boolean for whether the & Perl truth \\
                & user can skip it \\
\verb+constraint+ & Data::FormValidator & one string \\
                  & constraint &   \\
\verb+default_value+ & default form element value & one string \\
\verb+cols+ & cols attribute of textarea & one positive int \\
            & HTML element \\
\verb+rows+ & rows attribute of textarea & one positive int \\
            & HTML element \\
\verb+display_size+ & size attribute of text & one positive int \\
                    & HTML element \\
\verb+options+ & pull down menu choices & list of pairs: \\
               &                        & label \verb+=>+ value \\
\end{tabular}
\end{center}
\caption{Field html form statements (similar to
Table \ref{tab:fieldhtmlstats2}).}
\label{tab:fieldhtmlstats1}
\end{table}

I would have chosen \verb+size+ instead of
\verb+display_size+,\index{display size@\verb+display_size+} but
Template Toolkit has a virtual method called \verb+size+.

You may have as many values for the
\verb+html_form_options+\index{html form options@\verb+html_form_options+}
statement
as you like.  All of them must be pairs where the key is a string, number,
or ident and the value is also a string, number, or ident.  The key will
be the visible label of the option in the menu.  The value will be used
in the database.  Careful use of these can eliminate the need for certain
coding tables.  For example:

{\footnotesize
\begin{verbatim}
        html_form_options
            Yesterday => -1,
            Today     => 0,
            Tommorrow => 1;
\end{verbatim}
}

\subsection{Join Tables}

Join tables\index{join table!bigtop blocks}\index{bigtop!join table blocks}
represent a many-to-many relationship between two tables
defined elsewhere in the Bigtop file.  They actually become a third
table with foreign keys to the tables at the ends of the many-to-many
relationship.  The name of the \verb+join_table+ block is the name of the
third table.

Join table blocks can have the statements shown in
Table \ref{tab:jointablestats1}.  The \verb+joins+ statement
is required.

\begin{table}
\begin{center}
\begin{tabular}{l|l|l}
Keyword & Meaning & Values \\
\hline
\verb+joins+ & (required) which tables & pair of table names \\
             & are being joined        & \\
\verb+names+ & what the relationships  & pair of names \\
             & should be called        & \\
\verb+data+  & (repeatable) insert into \\
             & statement for SQL \\
\end{tabular}
\end{center}
\caption{Join table statements (similar to Table \ref{tab:jointablestats2}).}
\label{tab:jointablestats1}
\end{table}

If you don't supply a \verb+names+ statement, the many-to-many relationships
are named by taking the end point tables and appending `s' to their names.
You can change that by including a \verb+names+ statement.  Note that if you
want to name one table, you must name both tables.  Here's a complete
example:\index{join table!example}

{\footnotesize
\begin{verbatim}
    join_table fox_sock {
        joins fox => sock;
        names foxes => socks;
    }
\end{verbatim}
}

Join tables may also have field blocks just like the ones in ordinary table
blocks.

\subsection{Controllers}

Controller
blocks\index{controllers!bigtop blocks}\index{bigtop!controller blocks}
describe controller modules.  Most of these control
one table through using its model.  They may have statements, just like
other blocks.  They may also have method blocks, contol level literals,
and control level config blocks.  The later have their own subsections
below.

Controllers can have an optional type, which may affect generation:

{\footnotesize
\begin{verbatim}
    controller Name is some_type { }
\end{verbatim}
}

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Type & Affect on Generation \\
\hline
\verb+AutoCRUD+        & uses Gantry::Plugins::AutoCRUD       \\
\verb+CRUD+            & prepares for Gantry::Plugins::CRUD   \\
\verb+base_controller+ & controls the base module for the app \\
\verb+stub+            & (default) does nothing special       \\
\end{tabular}
\end{center}
\caption{Controller types.}
\label{tab:controltype}
\end{table}

\noindent
The valid types\index{controllers!valid bigtop types}
are shown in Table \ref{tab:controltype}.
There can be only one base controller and it cannot have a name:

{\footnotesize
\begin{verbatim}
    controller is base_controller {}
\end{verbatim}
}

\noindent
The controller level statements\index{controllers!bigtop statements}
are shown in Table \ref{tab:controlstats1}.

\begin{table}
\begin{center}
\begin{tabular}{l|l|l}
Keyword & Meaning & Values \\
\hline
\verb+no_gen+         & skip this controller & Perl truth \\
                      & (boolean)            & \\
\verb+location+       & absolute location of & one path \\
                      & this controller      & \\
\verb+rel_location+   & location of this & one path \\
                      & relative to base & \\
                      & controller       & \\
\verb+controls_table+ & name of controlled & one table name \\
                      & table              & \\

\verb+gen_uses+ & modules used by this    & list of installed \\
                & controller's gen module & modules \\
\verb+stub_uses+ & modules used by this   & list of installed \\
                 & controller's stub      & modules \\
\verb+uses+ & modules used by this        & list of installed \\
            & controller's modules        & modules \\
\verb+text_description+ & for AutoCRUD on & one string \\
                        & screen prompting \\
\verb+page_link_label+ & Nav link label for page & one string \\
\end{tabular}
\end{center}
\caption{Controller statements (similar to Table \ref{tab:controlstats2}).}
\label{tab:controlstats1}
\end{table}

\noindent
If you don't want the GEN module for the controller to be regenerated,
set \verb+no_gen+ to one (or your favorite true value).  Remember that
the stub is never regenerated, unless it is missing.

You must have either a \verb+location+ or a \verb+rel_location+ for
all controllers except the base controller.  Base controllers may have
an optional \verb+location+.  If you
use a \verb+location+, it may be any valid URL; \verb+rel_location+s will
have the app's root location prepended.

If you don't want the page to appear in site navigation links, don't include
a \verb+page_link_label+.
With the statements out of the way, let's look at the other things which
can go inside a controller block.

\subsubsection{Methods}

Methods\index{method!bigtop blocks}\index{bigtop!method blocks}
are full blocks, complete with types.  They look like this:

{\footnotesize
\begin{verbatim}
        method do_something is stub { ... }
\end{verbatim}
}

The type\index{method!valid bigtop types}
can be anything your Control backend understands.  Currently that
includes \verb+stub+ (which has only an opening comment, a declaration,
and parameter handling),
\verb+links+,\index{links, method type}
\verb+base_links+,\index{base links@\verb+base_links+}
\verb+main_listing+,\index{main listing}
\verb+AutoCRUD_form+,\index{AutoCRUD form@\verb+AutoCRUD_form+} and
\verb+CRDU_form+.\index{CRUD form@\verb+CRUD_form+}
The ones with form in their names are for use with
Gantry's CRUD schemes.  The ones with links their names are for navigation
methods.  \verb+base_links+ is suitable for use in a base controller as
\verb+do_main+, it shows a bulleted list of links, one for each controller
with a \verb+page_link_label+.  \verb+links+ is similar, but it is
for other controllers to call (often their templates do the calling).

Method statements are all legal no matter what type of method you have,
but they will be ignored, if you use them where they don't apply.
Thus, the statements in Table \ref{tab:methodstats1} are divided by
the type of method to which they apply.

\begin{table}
\begin{center}
\begin{tabular}{l|l|l}
Keyword & Meaning & Values \\
\hline
\multicolumn{3}{l}{All Types} \\
\hline
\verb+no_gen+ & Skip this method & Perl truth \\
\verb+extra_args+ & extra params sub & list of backquoted \\
                  & should accept    & variable names \\
                  &                  & (with sigils) \\
\hline
\multicolumn{3}{l}{\texttt{main\_listing}} \\
\hline
\verb+cols+   & columns in main listing    & list of field names \\
\verb+cols_labels+ & column labels         & list of labels \\
\verb+header_options+ & main table heading & list of options \\
                      & options (Add)      & \\
\verb+row_options+ & options for each main & list of options \\
                   & table row             & \\
\verb+limit_by+ & foreign key field to     & one field name \\
                & limit results            & \\
\hline
\multicolumn{3}{l}{\texttt{main\_listing} and links} \\
\hline
\verb+title+ & browser title for main & one string \\
             & listing page           & \\
\verb+html_template+ & what to use instead of   & one template name \\
                     & of results.tt or main.tt & \\
\hline
\multicolumn{3}{l}{forms} \\
\hline
\verb+extra_keys+ & extra keys for returned & list of key/value \\
                  & form hash               & pairs \\
\verb+fields+ & list of fields to include   & list of field names \\
              & on form                     & \\
\verb+all_fields_but+ & list of fields to exclude & list of field names \\
                      & from form HTML            & \\
\verb+form+ & name attribute of & one ident \\
            & form element \\
\end{tabular}
\end{center}
\caption{Method statements (similar to Table \ref{tab:methodstats2}).}
\label{tab:methodstats1}
\end{table}

Normally, main listing columns are labeled with their fields' labels.
If you want to override the label, just for the main listing, supply
\verb+col_labels+.  If your list runs out before the \verb+cols+ list,
the extras are again named for their fields.

The \verb+header_options+ values are similar to \verb+authors+ values
at the app level.  They can be single idents, like Add.  But they can
also be pairs, where the value is the URL to hit when the user chooses
the option.  By default the URL is the current controller with
\verb+/option+ appended.  This leads to the \verb+do_option+ method.
So, the default URL is formed by tacking the lower case of the option name
onto the end of the current location.

The \verb+row_options+ are similar to \verb+header_options+, but they
apply at the end of each row in the main listing.  There is one difference:
the default locations have the current row id appended to the URL.
If you supply non-default URLs, be sure to manually add \verb+$id+.

Use \verb+limit_by+ if you want a \verb+do_main+ which only shows some
of the rows from the underlying table.  The generated \verb+do_main+
will allow an optional parameter, which is the value of the foreign key
column named by this statement.  For example, suppose you had a table
called child and another called family.  If you add this to the child
controller:

{\footnotesize
\begin{verbatim}
limit_by family;
\end{verbatim}
}

\noindent
its \verb+do_main+ would allow an optional family id.  When one is provided,
only children from that family appear in the listing.  To make
this work well, you should add something like this to family controller:

{\footnotesize
\begin{verbatim}
row_options Children => `"/child/main/$id"`, Edit, Delete;
\end{verbatim}
}

\subsubsection{Controller Literals}

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Type & Destination \\
\hline
Location       & inside httpd.conf Location block \\
               & for the controller               \\
GantryLocation & inside GantryLocation block      \\
               & in Gantry::Conf file             \\
\end{tabular}
\end{center}
\caption{Controller literals and where their output goes.}
\label{tab:controllit}
\end{table}

There are two types of
literals\index{literal!in bigtop controllers}
that may appear inside controller blocks.
Like app level literals, they have a type name and a string.
These will be ignored unless you use a backend which understands them.
The HttpdConf Gantry backend understands
\verb+Location+,\index{Location, controller literal}
while
the Gantry Conf backend understands
\verb+GantryLocation+.\index{GantryLocation, controller literal}
Remember to put the literal value in a backquoted string (bare idents
are not allowed).  Also remember that if your literal value does not
have trailing whitespace, the backend will add one trailing blank line.

\subsubsection{Controller Configs}

As the app level has a config
block,\index{controllers!config blocks}\index{config block!in controllers}
so does each controller, even though
we almost always use the one at the app level and almost never use them
at the controller level.  These blocks allow you to provide conf info
that only one controller understands, or to override global conf info
with specific values for the benefit of individual controllers.

The syntax for these is exactly like their app level cousins, except that
the block must be placed inside a the only controller it will affect.
There is no way to have some conf info that is available to
a subset of controllers.  It is either at the app level for all or in
a controller block for one.

The most obvious use of controller level conf info is for
authorizing\index{auth, via controller config}
a page for a certain group.  Then we could say something like:

{\footnotesize
\begin{verbatim}
    controller Secret {
        config {
            auth_require group;
            auth_groups  Admin;
        }
    }
\end{verbatim}
}

\subsection{Sequences}

Sequences\index{sequences!bigtop blocks}\index{bigtop!sequence blocks}
are only understood by PostgreSQL.  Though sequences need to be
represented by a block, it must be empty.  Eventually, we may add sequence
statements to control minimum values and the like.  For now you get a
default sequence:

{\footnotesize
\begin{verbatim}
    sequence name {}
\end{verbatim}
}

\section*{Summary}

Now that you have seen all the syntax Bigtop has to offer, I wish you
happy editing.  It is frequently useful to pair the knowledge of this
chapter with a good understanding of tentmaker to gain the greatest
efficiencies.  The clicking in tentmaker can be tedious, but it has
some deep magic.  Typing in an editor requires careful attention to
syntax, but makes mass edits easier.  Use the style that makes sense
at the moment.
